import json
import random
from apps.goods.models import SKU
from django_redis import get_redis_connection
from django.contrib.auth import login, authenticate, logout
from django.http import HttpResponse
from django.http import JsonResponse
from django.views import View
from django_redis import get_redis_connection
from apps.users.models import User
from apps.verifications.libs.captcha.captcha import captcha
from shopping_mall.utils.loginrequired import LoginRequiredJSONMixin




# 用户名重复注册接口
class UsernameCount(View):

    def get(self, request, username):

        count = User.objects.filter(username=username).count()

        return JsonResponse({
            "code": 0,
            "errmsg": "ok",
            "count": count
        })

# 手机号重复注册接口
class MobileCountView(View):

    def get(self, request, mobile):

        count = User.objects.filter(mobile=mobile).count()

        return JsonResponse({
            "code": 200,
            "errmsg": "ok",
            "count": count
        })


# 用户注册接口的实现：
class RegisterView(View):

    def post(self, request):
        # 1:提取参数---请求体传参---request.body
        data = request.body.decode()
        data = json.loads(data)

        username = data.get("username")
        password = data.get("password")
        password2 = data.get("password2")
        mobile = data.get("mobile")
        sms_code = data.get("sms_code")
        allow = data.get("allow", False)

        # 2：校验参数
        # 略
        if password != password2:
            return JsonResponse("密码两次不一致")
        # 3： 数据处理
        try:
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
        except Exception as e:
            return JsonResponse({
                "code": 400,
                "errmsg": "数据库创建用户失败"
            })
        # TODO：短信验证码的校验
        conn = get_redis_connection("picture")
        sms_code_redie_mobile = conn.get(str(mobile))
        if not sms_code_redie_mobile:
            return JsonResponse({
                "code": 400,
                "errmsg": "短信验证码失效"
            })
        if sms_code_redie_mobile.decode() != sms_code:
            return JsonResponse({
                "code": 400,
                "errmg": "验证码输入错误"
            })

        # 状态保持
        login(request, user)
        # 4:构建响应
        return JsonResponse({
            "code": 0,
            "errmsg": "ok",

        })

# 返回图片验证码：
class PictureView(View):
    def get(self, request, uuid):

        text, image = captcha.generate_captcha()

        try:
            conn = get_redis_connection("picture")
            conn.setex(
                str(uuid),
                600,
                text
            )
        except Exception as e:
            return HttpResponse("redis数据库出现错误")


        return HttpResponse(
            image,
            content_type='image/jpeg'
        )

# 发送短信验证码：
class SMSCodeView(View):
    def get(self, request, mobile):
        # 1: 检验图形验证码是否正确
        image_code = request.GET.get("image_code")
        uuid = request.GET.get("image_code_id")
        conn = get_redis_connection("picture")
        image_code_redis = conn.get(str(uuid)).decode()
        conn.delete(str(uuid))
        if not image_code_redis:
            return JsonResponse({
                "code": 400,
                "errmsg": "图片验证码失效",
            })
        if image_code_redis.lower() != image_code.lower():
            return JsonResponse({
                "code": 400,
                "errmsg": "图片验证码输入错误"
            })

        # 2：发送手机验证码
        sms_code = "%06d" % random.randint(0, 999999)
        print("您的手机验证码是：", sms_code)

        conn.setex(str(mobile), 600, sms_code)
        # CCP().send_template_sms(
        #     mobile,
        #     [sms_code, 10],
        #     1
        # )

        # ccp_send_sms_code.delay(mobile, sms_code)
        return JsonResponse({
            "code": 0,
            "errmsg": "ok"
        })

# 用户名登陆接口实现
class LoginView(View):
    def post(self, request):
        data = json.loads(request.body.decode())
        username = data.get("username")
        password = data.get("password")
        remembered = data.get("remembered")

        user = authenticate(request, username=username, password=password)
        if user is None:
            return JsonResponse({
                "code": 400,
                "errmsg": "用户名或者密码错误"
            })
        login(request, user)

        if remembered != True:
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)
        response = JsonResponse({
            "code": 0,
            "errmsg": "ok"
        })
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)

        return response

# 退出登陆
class LoginOutView(View):
    def delete(self, request):
        # 1：清理session
        logout(request)
        response = JsonResponse({"code": 0, "errmsg": "ok"})
        # 2：清除前端的cookie
        response.delete_cookie("username")
        return response


# 用户中心页面展示：
class UserCenterDataView(LoginRequiredJSONMixin, View):

    def get(self, request):
        return JsonResponse({
            'code': 0,
            'errmsg': '个人中心',
             "info_data":{
                 "username" : request.user.username,
                "mobile" : request.user.mobile,
                "email" : request.user.email,
                "email_active" : request.user.email_active
                }
            })

# 修改密码：
class ChangePasswordView(View):
    def put(self, request):
        # 1:提取参数
        user = request.user
        data = json.loads(request.body.decode())
        old_password = data.get("old_password")
        new_password = data.get("new_password")
        new_password2 = data.get("new_password2")

        result = user.check_password(old_password)

        if not result:
            return JsonResponse({
                "code": 400,
                "errmsg": "密码错误"
            })
        if new_password != new_password2:
            return JsonResponse({
                "code": 400,
                "errmsg": "两次密码不一致"
            })
        try:
            user.set_password(new_password)
            user.save()
        except Exception as e:
            return JsonResponse({
                "code": 400,
                "errmsg": "新密码设置失败"
            })
        logout(request)

        response = JsonResponse({
            "code": 0,
            "errmsg": "ok"
        })
        response.delete_cookie("username")
        return response


# 用户浏览历史记录
class UserBrowseHistory(LoginRequiredJSONMixin, View):
    def post(self, request):

        user = request.user
        # 1、提取参数
        # 2、校验参数
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        if not sku_id:
            return JsonResponse({
                'code': 400,
                'errmsg': '缺少参数'
            }, status=400)

        try:
            SKU.objects.get(pk=sku_id, is_launched=True)
        except SKU.DoesNotExist as e:
            return JsonResponse({
                'code': 404,
                'errmsg': '商品已下架/不存在'
            }, status=404)

        # 3、数据/业务处理 —— 把访问的sku的id写入redis表示记录一条浏览历史

        # 3.1、获取"history"缓存配置的redis链接
        conn = get_redis_connection('history')
        p = conn.pipeline()
        # 3.2、历史记录写入缓存
        # 3.2.1、去重
        p.lrem(
            'history_%d' % user.id,
            0,  # 删除所有指定成员
            sku_id
        )
        # 3.2.2、插入列表头
        p.lpush(
            'history_%d' % user.id,
            sku_id
        )
        # 3.2.3、截断保留5个记录
        p.ltrim(
            'history_%d' % user.id,
            0,
            4
        )
        p.execute()  # 批量执行redis指令

        # 4、构建响应
        return JsonResponse({
            'code': 0,
            'errmsg': 'ok'
        })

        # 查看历史
    def get(self, request):

        user = request.user
        # 1、提取参数
        # 2、校验参数
        # 3、数据/业务处理 —— 用户浏览的sku商品信息返回(读redis获取最近浏览的历史sku.id, 读mysql获取sku详细信息)
        # 3.1、读redis获取浏览历史
        conn = get_redis_connection('history')
        # sku_ids = [b'6', b'3', b'4', b'14', b'15']
        sku_ids = conn.lrange(
            'history_%d' % user.id,
            0,
            -1
        )

        skus = []  # 用于记录返回sku商品的详细信息
        # 3.2、读mysql获取详细信息
        for sku_id in sku_ids:
            # sku_id = b'6'
            sku = SKU.objects.get(pk=int(sku_id))
            skus.append({
                'id': sku.id,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price
            })

        # 4、构建响应
        return JsonResponse({
            'code': 0,
            'errmsg': 'ok',
            'skus': skus
    })




